package controllers;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import models.ShortUrl;

import org.apache.commons.lang.StringUtils;

import play.Logger;
import play.db.jpa.JPA;
import play.mvc.Controller;

public class Application extends Controller {

	private static final String code = "0123456789abcdefghijklmnopqrstuvwxyz";

	public static void index() {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("recentlist", getRecentShortUrlList());
		map.put("shortUrlPrefix", getShortUrlPrefix());
		renderTemplate("Application/index.html", map);
	}

	public static void shorten(String longurl) {
		Logger.info(longurl);

		Map<String, Object> map = new HashMap<String, Object>();

		if (!isValidLongUrl(longurl)) {
			map.put("error", "Invalid long url!");
		} else {
			if (isSameDomainUrl(longurl)) {
				map.put("shorturl", longurl);
			} else {
				ShortUrl su = ShortUrl.find("byLongUrl", longurl).first();
				if (su != null) {
					map.put("shorturl", getShortUrlPrefix() + su.opCode);
				} else {
					Query query = JPA.em().createQuery(
							"select max(su.opNum) from ShortUrl su");
					int max = 0;
					if (query.getSingleResult() != null) {
						max = (Integer) query.getSingleResult();
					}

					ShortUrl newSu = new ShortUrl();
					newSu.opNum = max + 1;
					newSu.opCode = getOpCodeByNum(newSu.opNum);
					newSu.longUrl = longurl;
					newSu.accessTimes = 0;
					newSu.save();
					map.put("shorturl", getShortUrlPrefix() + newSu.opCode);

				}
			}
		}

		map.put("recentlist", getRecentShortUrlList());
		map.put("shortUrlPrefix", getShortUrlPrefix());

		renderTemplate("Application/index.html", map);

	}

	public static void expand(String op) {
		Logger.info(op);
		ShortUrl su = ShortUrl.find("byOpCode", op).first();
		if (su != null) {
			su.accessTimes++;
			su.save();
			redirect(su.longUrl);
		} else {
			notFound();
		}

	}

	private static boolean isValidLongUrl(String longurl) {
		try {
			URL url = new URL(longurl);
		} catch (MalformedURLException e) {
			return false;
		}

		return true;
	}

	private static boolean isSameDomainUrl(String longurl) {
		try {
			URL url = new URL(longurl);
			if (StringUtils.equalsIgnoreCase(url.getHost(), request.host)) {
				return true;
			}
		} catch (MalformedURLException e) {
			return true;
		}

		return false;
	}

	private static List<ShortUrl> getRecentShortUrlList() {
		Query query = JPA.em().createQuery(
				"select s from ShortUrl s order by s.opNum desc");
		query.setMaxResults(30);
		List<ShortUrl> recentShortUrlList = query.getResultList();
		return recentShortUrlList;
	}

	private static String getShortUrlPrefix() {
		StringBuilder shortUrlBuilder = new StringBuilder();
		if (request.secure) {
			shortUrlBuilder.append("https://");
		} else {
			shortUrlBuilder.append("http://");
		}

		shortUrlBuilder.append(request.host);
		shortUrlBuilder.append("/");

		return shortUrlBuilder.toString();

	}

	private static String getOpCodeByNum(int num) {
		StringBuffer opCodeBuffer = new StringBuffer();
		int temp = num;
		while (temp > 0) {
			opCodeBuffer.insert(0, code.charAt(temp % code.length()));
			temp /= code.length();
		}

		return opCodeBuffer.toString();

	}

	public static void main(String[] args) throws MalformedURLException {
		URL url = new URL("http://www.xmxsuperstar.com");
		System.out.println(url.toString());

	}
}